--脚本说明
--该脚本主要用于自动创建用户、网关、拨号方案。
--用户可以注册到FreeSWITCH，并能通过网关进行外呼
--该脚本同时有一个配置文件，config.ini，用于配置需要的变量。

local FS_DIR = "/usr/local/freeswitch";
local USER_DIR = FS_DIR .. "/conf/directory/default";
local DIALPLAN_DIR = FS_DIR .. "/conf/dialplan/public";
local GATEWAY_DIR = FS_DIR .. "/conf/sip_profiles/external";
local FSCLI_PATH = FS_DIR .. "/bin/fs_cli";

--for test
USER_DIR = "."
DIALPLAN_DIR = "."
GATEWAY_DIR = "."
	
print(USER_DIR)
print(DIALPLAN_DIR)
print(GATEWAY_DIR)

GATEWAY_TEMPLATE =[[
<include>
        <gateway name="gw_%id%">
	        <param name="username" value="%sipid%"/>
	        <param name="password" value="%sippwd%"/>
	        <param name="realm" value="%sipserver%:%sipport%"/>
	        <param name="from-domain" value="%sipserver%:%sipport%"/>
	        <param name="expire-seconds" value="600"/>
	        <param name="register" value="true"/>
        </gateway>
</include>
]]

USER_TEMPLATE =[[
<include>
  <user id="%id%">
    <params>
      <param name="password" value="$${default_password}"/>
      <param name="vm-password" value="%id%"/>
    </params>
    <variables>
      <variable name="toll_allow" value="domestic,international,local"/>
      <variable name="accountcode" value="%id%"/>
      <variable name="user_context" value="default"/>
      <variable name="effective_caller_id_name" value="%id%"/>
      <variable name="effective_caller_id_number" value="%id%"/>
      <variable name="outbound_caller_id_name" value="$${outbound_caller_name}"/>
      <variable name="outbound_caller_id_number" value="$${outbound_caller_id}"/>
      <variable name="callgroup" value="techsupport"/>
    </variables>
  </user>
</include>
]]

DIALPLAN_TEMPLATE =[[
<include>
	<extension name="%id%_Test_Extension">
		<condition field="destination_number" expression="^%id%(\d{4,15})$">
	        <action application="set" data="ringback=${us-ring}"/>
	        <action application="set" data="call_timeout=30"/>
	        <action application="bridge" data="sofia/gateway/gw_%id%/${destination_number}"/>
	    </condition>
	</extension>

	<extension name="%id%_Extension">
	    <condition field="caller_id_name" expression="^%id%$">
	        <action application="set" data="ringback=${us-ring}"/>
	        <action application="set" data="call_timeout=30"/>
	        <action application="bridge" data="sofia/gateway/gw_%id%/${destination_number}"/>
	    </condition>
	</extension>
</include>
]]

function createGateway(userId, sipId, sipPwd, sipServer, sipPort)
	local newTxt = string.gsub(GATEWAY_TEMPLATE,"%%id%%",userId);
	newTxt = string.gsub(newTxt,"%%sipid%%",sipId);
	newTxt = string.gsub(newTxt,"%%sippwd%%",sipPwd);
	newTxt = string.gsub(newTxt,"%%sipserver%%",sipServer);
	newTxt = string.gsub(newTxt,"%%sipport%%",sipPort);

	local fileName = GATEWAY_DIR .. "/gw_" .. userId .. ".xml"; 
	writeFile(fileName, newTxt);
end

function  createDialplan(userId)
	local newTxt = string.gsub(DIALPLAN_TEMPLATE,"%%id%%",userId);
	local fileName = DIALPLAN_DIR .. "/01_" .. userId .. ".xml";
	writeFile(fileName, newTxt);
end

function createUser(userId)
	local newTxt = string.gsub(USER_TEMPLATE,"%%id%%",userId);
	local fileName = USER_DIR .. "/" .. userId .. ".xml";
writeFile(fileName, newTxt);
end

function writeFile(fileName, fileContent)
	local file = io.open(fileName, "w");
	file:write(fileContent);
	file:close();
end

function readConfig(configFile)
	local file = io.open(configFile, "r");
	assert(file);
	local data = file:read("*a"); 
    file:close();

    local _,_,userId = string.find(data, "userId=(.-)%s");
    local _,_,sipId = string.find(data, "sipId=(.-)%s");
    local _,_,sipPwd = string.find(data, "sipPwd=(.-)%s");
    local _,_,sipServer = string.find(data, "sipServer=(.-)%s");
    local _,_,sipPort = string.find(data, "sipPort=(%d*)");
    print("userId:" .. userId);
    print("sipId:" .. sipId);
    print("sipPwd:" .. sipPwd);
    print("sipServer:" .. sipServer);
    print("sipPort:" .. sipPort);
    return userId, sipId, sipPwd, sipServer, sipPort;
end

function portIsOpen(serverIp, serverPort)
	local cmd = "timeout 2 bash -c \"</dev/tcp/" ..serverIp .. "/" .. serverPort .. "\"; echo $?";
	local result = os.execute(cmd);
	return (cmd == "0");
end

function sleep(n)
	os.execute("sleep " .. tonumber(n))
end

function executeFS(cmd)
	local result = os.execute(FSCLI_PATH .. " -x \"" .. cmd .. "\"");
	return result;
end


function main()
	local userId, sipId, sipPwd, sipServer, sipPort = readConfig("./config.ini");
	print("start to create gateway user for FreeSWITCH.");
	print("userId:" .. userId);
    print("sipId:" .. sipId);
    print("sipPwd:" .. sipPwd);
    print("sipServer:" .. sipServer);
    print("sipPort:" .. sipPort);

    print("checking sip server port ...");
    local isOpen = portIsOpen(sipServer, sipPort);
    print(string.format("sip server port status: %s",isOpen));

	createUser(userId);
	createDialplan(userId);
	createGateway(userId, sipId, sipPwd, sipServer, sipPort);

	print("create success, start to refresh freeswitch");
	executeFS("reloadxml");
	executeFS("sofia profile external rescan reloadxml");

	sleep(5);
	local status = executeFS("sofia status");
	print(string.format("sofia status:\n%s" .. status));
end

main();
